/* 
 * File:   Date.h
 * Author: Muhammad Anis
 */
#include "..\Utilities\boolean.h"

#ifndef DATE_H
#define	DATE_H
#define KABISAT_DAYS    366
#define COMMON_DAYS     365
// 1 Januari pada tahun 1990, hari Senin
#define FIRST_DAY_IN_BASE 1
#define BASE_YEAR 1990
/**
 * Day enumeration
 */
typedef enum {
    Ahad, Senin, Selasa, Rabu, Kamis, Jumat, Sabtu, Undef
} Day;

/**
 * Definition of Date
 */
typedef struct {
    int year;
    int month;
    int day;
} Date;

/**
 * Fungsi untuk membuat Date
 * @param year Tahun Date
 * @param month Bulan Date
 * @param day Day Date
 * @return Date yang terdiri year, month dan day
 */
Date MakeDate(int year, int month, int day);

/**
 * Check if a date has valid value
 * @param year Year of associated Date
 * @param month Month of associated Date
 * @param day Day of associated Date
 * @return true if Date valid
 */
int IsDateValid(int year, int month, int day);

/* Getter and Setter Area */
/**
 * Get year part of Date
 * @param d Associated Date
 * @return Year part of Date
 */
int GetYear(Date d);

/**
 * Get Month Part of Date
 * @param d Associated Date
 * @return Month part of date
 */
int GetMonth(Date d);

/**
 * Get Day part of Date
 * @param d Associated Date
 * @return Day part of Date
 */
int GetDay(Date d);

/**
 * I.S : Independent
 * F.S : Year value of date set to year
 * @param year Year value
 * @param d Associated Date
 */
void SetYear(int year, Date* d);

/**
 * I.S : Independent
 * F.S : Month value of date set to month
 * @param month Month Value
 * @param d Associated Date
 */
void SetMonth(int month, Date* d);

/**
 * I.S : Independent
 * F.S : Day value of date set to day
 * @param day Day Value
 * @param d Associated Date
 */
void SetDay(int day, Date* d);

/**
 * Check if given year is Kabisat
 * @param year Given year
 * @return true if year is Kabisat
 */
boolean IsYearKabisat(int year);

/**
 * I.S : Independent
 * F.S : Print date to screen
 * @param d Associated Date
 */
void PrintDate(Date d);

/**
 * Get Second from Date started from year 1900
 * @param d Associated Date
 * @return Seconds that has been passed
 */
long long DateToSecond(Date d);

/**
 * Check if a date is less than another Date
 * @param d1 First Date
 * @param d2 Second Date
 * @return true if d1 < d2
 */
boolean DateLessThan(Date d1, Date d2);

/**
 * Check if d1 is equal with d2
 * @param d1 First date
 * @param d2 Second Date
 * @return true if d1 = d2
 */
boolean EqDay(Date d1, Date d2);


/**
 * Returns next day of given date
 * @param d Now
 * @return Tomorrow
 */
Date NextDay(Date d);

/**
 * Returns previous day of given date
 * @param d Now
 * @return Yesterday
 */
Date Yesterday(Date d);

/**
 * Add D1 with D2
 * @param d1 First Date
 * @param d2 Second Date
 * @return D1 + D2
 */
Date AddDate(Date d1, Date d2);

/**
 * I.S : d1 and d2 is defined
 * F.S : d1 = d1 + d2
 * @param d1 First Date
 * @param d2 Second Date
 */
void AfterDate(Date* d1, Date d2);

/**
 * Returns absolute difference value in d1 and d2
 * @param d1 First day
 * @param d2 Second day
 * @return sum of day of differences
 */
int DaysDiff(Date d1, Date d2);

/**
 * Returns Date with given seconds elapsed since 1900
 * @param seconds seconds elapsed
 * @return Date with elapsed seconds = seconds
 */
Date SecondToDate(long long seconds);
/**
 * Returs first Day in the given year and month
 * @param date date
 * @return day of date
 */
Day GetFirstDay(int year, int month);
/**
 * Returns the string representation of day
 * @param day day
 * @return string of day
 */
char* GetDayString(Day day);
/**
 * Returns maximum day count in a month
 * @param month month 
 * @param year year
 * @return count of days
 */
int MaxDaysInMonth(int month, int year);
#endif	/* DATE_H */
